package gov.pbc.nn.kjgl.meetings.view;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.entity.Meeting;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.meetings.dao.MeetingDao;
import gov.pbc.nn.kjgl.meetings.dao.MeetingJdbcDao;
import gov.pbc.nn.uflo.entity.Opinion;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.dorado.view.widget.form.autoform.AutoFormElement;

@Component("meetingPR")
public class MeetingPR {

	@Autowired
	private MeetingDao meetingDao;
	@Autowired
	private MeetingJdbcDao meetingJdbcDao;

	@DataProvider
	public void getMeeting(Page<Meeting> page, Criteria criteria) {
		meetingJdbcDao.getMeeting(page, criteria);
	}

	@DataProvider
	public void getMeetingByCommit(Page<Meeting> page, Criteria criteria) {
		meetingDao.getMeetingByCommit(page, criteria);
	}

	@DataProvider
	public void getMeetingByRelease(Page<Meeting> page, Criteria criteria) {
		meetingJdbcDao.getMeetingByRelease(page, criteria);
	}

	@DataProvider
	public List<Map<String, Object>> getAssessor() {
		return meetingDao.getAssessor();
	}

	@Transactional
	@DataResolver
	public void saveMeeting(List<Meeting> meeting) {
		if (meeting.size() > 0) {
			for (Meeting m : meeting) {
				meetingDao.saveMeeting(m);
			}
		}
	}

	@Transactional
	@DataResolver
	public void saveOneMeeting(List<Meeting> meeting) {
		if (meeting.size() > 0) {
			for (Meeting m : meeting) {
				meetingDao.saveOneMeeting(m);
			}
		}
	}

	@Transactional
	@Expose
	public void deleteMeeting(List<String> ids) {
		if (ids.size() > 0) {
			for (String id : ids) {
				meetingDao.deleteMeeting(id);
			}
		}
	}

	@Transactional
	@Expose
	public void handleMeeting(Map<String, Object> parameter) {
		List<String> ids = (List<String>) parameter.get("ids");
		int state = (int) parameter.get("state");
		String opinion = (String) parameter.get("opinion");
		if (ids.size() > 0) {
			for (String id : ids) {
				Meeting me = meetingDao.selectMeetingById(id);
				if (me != null) {
					if (state == 5) {
						meetingDao.commitMeeting(me);
					} else if (state == 20) {
						meetingDao.backMeeting(me);
					} else if (state == 10) {
						int cld = (int) parameter.get("cld");
						String czName = (String) parameter.get("czName");
						String czUsername = (String) parameter.get("czUsername");
						meetingDao.agree(me, opinion, cld, czName, czUsername);
					} else if (state == 11) {
						meetingDao.disagree(me, opinion);
					}
				}
			}
		}
	}

	@Transactional
	@Expose
	public void releaseMeeting(Map<String, Object> parameter) {
		meetingDao.releaseMeeting(parameter);
	}

	@Transactional
	@Expose
	public void insertMeetingUser(Map<String, Object> parameter) {
		String id = (String) parameter.get("meetingId");
		List<String> username = (List<String>) parameter.get("username");
		List<String> cname = (List<String>) parameter.get("cname");
		List<String> ename = (List<String>) parameter.get("ename");
		Meeting me = meetingDao.selectMeetingById(id);
		for (int i = 0; i < username.size(); i++) {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("username", username.get(i));
			param.put("cname", cname.get(i));
			param.put("ename", ename.get(i));
			meetingDao.insertMeetingUser(me, param);
		}
	}

	/**
	 * 前台js控制,当前登录人岗位为处长的时候设置id为afm的AutoFormElement的visible为false
	 * 
	 * @param afm
	 */
	public void onInit(AutoFormElement afm) {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> ls = SecurityUtils.getUserByRoleForDept(dept.getCDept().getId(), Constants.ROLE_CZ);
		for (IUser u : ls) {
			if (ContextHolder.getLoginUserName().equals(u.getUsername())) {
				afm.setVisible(false);
				return;
			}
		}
	}

	/**
	 * 根据MeetingId获取相应的参会人员
	 * 
	 * @param id
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> getMeetingXq(String id) {
		return meetingDao.getMeetingXq(id);
	}

	@Expose
	public boolean getMeetingDeptByMeetingId(String id) {
		return meetingDao.getMeetingDeptByMeetingId(id);
	}

	/**
	 * 维护参会人员
	 * 
	 * @param param
	 */

	@Transactional
	@Expose
	public void saveMeetingUser(Map<String, Object> param) {
		List<String> ls = (List<String>) param.get("list");
		List<Boolean> join = (List<Boolean>) param.get("listValue");
		if (!ls.isEmpty()) {
			for (int i = 0; i < ls.size(); i++) {
				meetingDao.saveMeetingUser(ls.get(i), join.get(i));
			}
		}
	}

	/**
	 * Meeting查询
	 * 
	 * @param page
	 */
	@DataProvider
	public void getMeetingAll(Page<Meeting> page, String i, Criteria criteria) {
		meetingJdbcDao.getMeetingAll(page, i, criteria);
	}

	/**
	 * 根据id删除对应的MeetingUser
	 * 
	 * @param list
	 */

	@Transactional
	@Expose
	public void deleteMeetingUser(List<String> list) {
		for (String id : list) {
			meetingDao.deleteMeetingUser(id);
		}
	}

	@DataProvider
	public List<Opinion> getOpinion(String busId) {
		return meetingDao.getOpinion(busId);
	}

	@DataProvider
	public List<Map<String, Object>> getMeetingXqDelete(String meetingId) {
		return meetingJdbcDao.getMeetingXqDelete(meetingId);
	}

	/**
	 * 上传附件
	 * 
	 * @param file
	 * @param parameter
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	@FileResolver
	public String process2(UploadFile file, Map<String, Object> params) throws Exception {
		String basePath = Configure.getString("MEETING_FILE_UPLOAD_PATH");
		if (StringUtils.isEmpty(basePath)) {
			throw new IllegalArgumentException("必须指定档案文件上传的基本地址");
		}
		String returnValue = null;
		try {
			String pathArr = "会议附件";
			Path path = Paths.get(basePath, pathArr);
			if (!Files.isDirectory(path)) {
				path = Files.createDirectories(path);
			}
			path = path.resolve(UUID.randomUUID().toString());
			File destFile = Files.createFile(path).toFile();
			file.transferTo(destFile);
			returnValue = destFile.getPath();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return returnValue;
	}

	/**
	 * 下载附件
	 * 
	 * @param parameter
	 * @return
	 * @throws IOException
	 */
	@FileProvider
	public DownloadFile download(Map<String, Object> params) throws IOException {
		Meeting m = this.getMeetingById((String) params.get("meetingId"));
		String fileName = m.getFileName();
		String path = m.getFileUrl();
		InputStream stream = new FileInputStream(path);
		DownloadFile file = new DownloadFile(fileName, stream);
		return file;
	}

	public Meeting getMeetingById(String Id) {
		DetachedCriteria query = DetachedCriteria.forClass(Meeting.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("id", Id));
		List<Meeting> ls = (List<Meeting>) this.meetingDao.query(query);
		if (ls.size() > 0) {
			return ls.get(0);
		}
		return null;
	}

	@Transactional
	@Expose
	public void meetingComplete(String id) {
		Meeting meeting = this.getMeetingById(id);
		meeting.setState(100);
		this.meetingDao.update(meeting);
	}

	@DataProvider
	public List<IUser> getCzByDept() {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> ls = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(), Constants.ROLE_CZ);
		if (ls.size() > 0) {
			return ls;
		}
		return null;
	}
}
